package com.lanwf.admin.utils;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.PathKit;
import com.jfinal.upload.UploadFile;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import sun.net.www.protocol.https.Handler;

import javax.net.ssl.HttpsURLConnection;
import java.awt.*;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.text.Collator;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 发送请求帮助类
 *
 * @author lc
 */
public class CommonUtil {

    public static Map< String, Object > cache = new HashMap<>( );

    private static Logger log = Logger.getLogger(CommonUtil.class);
    //用来产生随机验证码的
    private static Random rand = new Random( );
    private static String[] str = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

    //常见的图片格式
    private static final String[] picture_sort = {"BMP", "JPEG", "JPG", "GIF", "PSD", "PNG", "TIFF", "TGA", "EPS"};


    public static JSONObject httpsRequestToJsonObject(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            String buffer = httpsRequest(requestUrl, requestMethod, outputStr);
            jsonObject = JSONObject.parseObject(buffer);
        } catch (Exception ce) {
            log.error("连接超时：" + ce.getMessage( ));
        }
        return jsonObject;
    }

    /**
     * url 请求 ssl
     * 数据格式 [form 表单式]
     *
     * @param requestUrl
     * @param requestMethod
     * @param output
     * @return
     * @throws Exception
     */
    public static String httpsRequest(String requestUrl, String requestMethod, String output) {
        StringBuffer buffer = null;
        try {
            URL url = new URL(null, requestUrl, new Handler());
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            if (null != output) {
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes("UTF-8"));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            connection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return buffer.toString();
    }


    /**
     * 获取几位随机数
     *
     * @param num 位数
     * @return
     */
    public static String getRandom(int num) {
        //存放产生的随机数
        String sms;
        //生成六位数的随机数
        StringBuffer buf = new StringBuffer( );
        for (int i = 0; i < num; i++) {
            buf.append(str[rand.nextInt(10)]);
        }
        sms = buf.toString( );
        return sms;
    }

    /**
     * 获取uuid 转小写
     *
     * @return
     */
    public static String getUUIDToLower( ) {
        return UUID.randomUUID( ).toString( ).trim( ).replace("-", "").toLowerCase( );
    }

    /**
     * 获取uuid 转大写
     *
     * @return
     */
    public static String getUUIDToUpper( ) {
        return UUID.randomUUID( ).toString( ).trim( ).replace("-", "").toUpperCase( );
    }


    /**
     * list集合按字典顺序排序
     *
     * @param list
     * @return
     */
    public static List chineseSort(List< String > list) {
        if (list == null || list.isEmpty( )) {
            return list;
        }
        Collections.sort(list, (o1, o2) -> {
            Comparator< Object > com = Collator.getInstance(Locale.CHINA);
            return com.compare(o1, o2);
        });
        return list;
    }

    public static String[] splitIgnoreCase(String str) {
        return str.split("[,，]+");
    }


    /**
     * 对象序列化成字节码数据
     *
     * @param obj
     * @return
     */
    public static byte[] setSerialize(Object obj) {
        ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream( );
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(byteOutStream);
            oos.writeObject(obj);
            oos.close( );
            return byteOutStream.toByteArray( );
        } catch (Exception e) {
            e.printStackTrace( );
        } finally {
            try {
                oos.close( );
            } catch (IOException e) {
                e.printStackTrace( );
            }
        }
        return null;
    }

    /**
     * 反序列化  字节码文件转对象
     *
     * @param bytes
     * @return
     */
    public static Object getSerialize(byte[] bytes) {
        ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(byteInStream);
            return ois.readObject( );
        } catch (Exception e) {
            e.printStackTrace( );
        } finally {
            try {
                ois.close( );
            } catch (IOException e) {
                e.printStackTrace( );
            }
        }
        return null;
    }


    /**
     * 添加到缓存中
     *
     * @param key
     * @param value
     */
    public static void setCache(String key, Object value) {
        cache.put(key, value);
    }

    /**
     * 从缓存中取出
     *
     * @param key
     * @return
     */
    public static Object getCache(String key) {
        return cache.get(key);
    }

    /**
     * 获取文件大小 格式化单位
     *
     * @param filepath
     * @return KB, MB, GB
     */
    public static String formatFileUnit(UploadFile filepath) {
        long length = filepath.getFile( ).length( );
        System.err.println("the tile size is :" + length);
        return sizeChange(length);
    }

    public static String sizeChange(long length) {
        if (length < 1024 * 1024) {
            long z = length / 1024;
            return "" + (z) + "KB";
        }

        if (length > 1024 * 1024 && length < 1024 * 1024 * 1024) {
            long z = length / (1024 * 1024);
            return "" + (z) + "MB";
        }

        if (length > 1024 * 1024 * 1024) {
            long z = length / (1024 * 1024 * 1024);
            long m = length % (1024 * 1024 * 1024) / (1000 * 1000 * 10);
            return "" + (z) + "." + m + "GB";
        }
        return "0KB";
    }

    public static String fileSize(long folderSize) {
        if (folderSize <= 0) {
            return "0KB";
        }
        long length = folderSize;
        return sizeChange(length);
    }

    /**
     * 获取文件路径
     *
     * @param uploadFile
     * @param folder
     * @return
     */
    public static String getFilePath(UploadFile uploadFile, String folder) {
        if (uploadFile != null) {
            return "/upload" + folder + uploadFile.getFileName( );
        }
        return "";
    }

    /**
     * 删除文件
     *
     * @param filePath
     */
    public static boolean deleteFile(String filePath) {
        if (StringUtils.isNotBlank(filePath)) {
            String path = PathKit.getWebRootPath( ) + filePath;
            return new File(path).delete( );
        }
        return false;
    }

    /**
     * 文件上传
     *
     * @param img
     * @param folder
     * @return
     */
    public static String imgUpload(String img, String folder) {
        if (StringUtils.isBlank(img) || StringUtils.isBlank(folder)) {
            return "";
        }
        File file = new File(img);
        String f = PathKit.getWebRootPath( ) + "/upload/" + folder;
        File file1 = new File(f);
        if (!new File(f).exists( )) {
            file1.mkdirs( );
        }

        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            in = new FileInputStream(file);
            out = new FileOutputStream(new File(f, file.getName( )));

            byte[] bytes = new byte[1024];
            int l;
            while ((l = in.read(bytes)) != -1) {
                out.flush( );
                out.write(bytes, 0, l);
            }
        } catch (IOException e) {
            e.printStackTrace( );
        } finally {
            try {
                in.close( );
                out.flush( );
                out.close( );
            } catch (IOException e) {
                e.printStackTrace( );
            }
        }
        return "/upload/" + folder + "/" + file.getName( );
    }


    /**
     * 迭代删除文件夹
     *
     * @param dirPath 文件夹路径
     */
    public static void deleteDir(String dirPath) {
        File file = new File(dirPath);
        if (file.isFile( )) {
            file.delete( );
        } else {
            File[] files = file.listFiles( );
            if (files == null) {
                file.delete( );
            } else {
                for (int i = 0; i < files.length; i++) {
                    deleteDir(files[i].getAbsolutePath( ));
                }
                file.delete( );
            }
        }
    }



    //时间间隔(天)
    public static int intervalday(Date sDate, Date eDate) {

        try {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            sDate=sdf.parse(sdf.format(sDate));
            eDate=sdf.parse(sdf.format(eDate));
            Calendar cal = Calendar.getInstance();
            cal.setTime(sDate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(eDate);
            long time2 = cal.getTimeInMillis();
            long between_days=(time2-time1)/(1000*3600*24);

            return Integer.parseInt(String.valueOf(between_days));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;

    }

    //时间间隔(天)
    public static int intervalday(String sDate, String eDate) {
        Date startDate = format(sDate, "yyyy-MM-dd");
        Date endDate = format(eDate, "yyyy-MM-dd");
        return intervalday(startDate, endDate);
    }

    public static Date format(String date, String patten) {
        SimpleDateFormat sdf = new SimpleDateFormat(patten);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date formatDate(String data, String patten) {
        SimpleDateFormat sdf = new SimpleDateFormat(patten);

        try {
            return sdf.parse(data);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 给定一个整数数组 nums 和一个整数目标值 target，请你在该数组中找出 和为目标值 target  的那 两个 整数，并返回它们的数组下标。
     *
     * 你可以假设每种输入只会对应一个答案。但是，数组中同一个元素在答案里不能重复出现。
     *
     * 你可以按任意顺序返回答案。
     * @param args
     * 输入：nums = [2,7,11,15], target = 9
     * 输出：[0,1]
     * 解释：因为 nums[0] + nums[1] == 9 ，返回 [0, 1] 。
     *
     */
    public static void main(String[] args) throws IOException {
/*        BufferedImage image = new BufferedImage(108, 40, 1);
        drawGraphic("gs45", image);
        File file = new File("d://abc.jpeg");
        ImageIO.write(image, "jpeg", file);*/

        String s = encodeToBase64ThenDecrypt("select * from data_user where name like '%刘超%' ");
        System.err.println(s);
        System.err.println("------------------");
        String s1 = decodeToBase64ThenDecrypt(s);
        System.err.println(s1);

    }
    protected static final char[] charArray = "3456789ABCDEFGHJKMNPQRSTUVWXY".toCharArray();
    protected static final Font[] RANDOM_FONT = new Font[]{new Font("Dialog", 1, 33), new Font("DialogInput", 1, 34), new Font("Serif", 1, 33), new Font("SansSerif", 1, 34), new Font("Monospaced", 1, 34)};
    public static void drawGraphic(String randomString, BufferedImage image) {
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        ThreadLocalRandom random = ThreadLocalRandom.current();
        g.setColor(getRandomColor(210, 250, random));
        g.fillRect(0, 0, 108, 40);
        Color color = null;

        int i;
        for(i = 0; i < 20; ++i) {
            color = getRandomColor(120, 200, random);
            g.setColor(color);
            String rand = String.valueOf(charArray[random.nextInt(charArray.length)]);
            g.drawString(rand, random.nextInt(108), random.nextInt(40));
            color = null;
        }

        g.setFont(RANDOM_FONT[random.nextInt(RANDOM_FONT.length)]);

        for(i = 0; i < randomString.length(); ++i) {
            int degree = random.nextInt(28);
            if (i % 2 == 0) {
                degree *= -1;
            }

            int x = 22 * i;
            int y = 21;
            g.rotate(Math.toRadians((double)degree), (double)x, (double)y);
            color = getRandomColor(20, 130, random);
            g.setColor(color);
            g.drawString(String.valueOf(randomString.charAt(i)), x + 8, y + 10);
            g.rotate(-Math.toRadians((double)degree), (double)x, (double)y);
        }

        g.setColor(color);
        BasicStroke bs = new BasicStroke(3.0F);
        g.setStroke(bs);
        QuadCurve2D.Double curve = new QuadCurve2D.Double(0.0D, (double)(random.nextInt(32) + 4), 54.0D, 20.0D, 108.0D, (double)(random.nextInt(32) + 4));
        g.draw(curve);
        g.dispose();
    }

    public static Color getRandomColor(int fc, int bc, ThreadLocalRandom random) {
        if (fc > 255) {
            fc = 255;
        }

        if (bc > 255) {
            bc = 255;
        }

        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }


    private static String KEY = "12345678901234567890abcd";

    /**
     * 加密
     * @param str 字符
     * @return
     */
    public static String encodeToBase64ThenDecrypt(String str){
        if(StringUtils.isBlank(str)) return "";

        BASE64Encoder base64Encoder = new BASE64Encoder();
        String encode = base64Encoder.encode(str.getBytes());
        return TripleDes.encrypt3DES(encode, KEY);
    }

    /**
     * 解密
     * @param decry 字符
     * @return
     */
    public static String decodeToBase64ThenDecrypt(String decry) {
        if(StringUtils.isBlank(decry)) return "";

        String base64Str = TripleDes.decrypt3DES(decry, KEY);
        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] bytes = new byte[0];
        try {
            bytes = base64Decoder.decodeBuffer(base64Str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(bytes);
    }
}
